package map_;

import java.util.HashMap;
import java.util.Map;

public class Map_ {
    public static void main(String[] args) {

        Map map=new HashMap();
        /**
         * 1.Map用于保存具有映射关系的数据：key-value
         * 2.key是按照hash存放的，所以HashMap也是无序的
         * 3.key不可以重复，可以为null
         * 4.value可以重复
         * 5.key-value存在单向一对一关系，根据key总能找到对应的value
         */
        map.put("黎旭",20);
        /**
         * put时又来到了我们熟悉的 put方法
         * todo HashMap类
         *      public V put(K key, V value) {
         *         return putVal(hash(key), key, value, false, true);
         *     }
         * 存放的时候我们的key和value时存在了HashMap$Node中
         * todo
         *      Node<K,V> newNode(int hash, K key, V value, Node<K,V> next) {
         *         return new Node<>(hash, key, value, next);
         *     }
         *
         * todo
         *      Node(int hash, K key, V value, Node<K,V> next) {
         *             this.hash = hash;
         *             this.key = key;
         *             this.value = value;
         *             this.next = next;
         *         }
         *
         */
        map.put(null,20);
        map.put(null,null);//替换机制，新的value会覆盖原来的value
        map.put("star",null);
        System.out.println("1"+map);
        /**
         * 1. idea在debug时偷偷调用toString方法，在HashMap追源码时产生的疑惑
            2. HashMap的entrySet()和keySet()方法真的创建了一个存满数据的set对象吗？
            3. 内部类：EntrySet类没有构造器，那它是怎么初始化的呢？
            4. 为什么集合框架中一定要利用好迭代器iterator()来获取入口？
            5. entrySet().size()获取的值是该set的实际大小吗？
         https://blog.csdn.net/m0_56079407/article/details/123624985
         */
        map.entrySet();
        System.out.println("2"+map.entrySet());//{null=null, star=null, 黎旭=20}
        System.out.println("3"+map.keySet());//3[null, star, 黎旭]
        System.out.println("4  map.entrySet().getClass()  "+map.entrySet().getClass());
        for (Object e : map.entrySet()) {
            System.out.println("5 e="+e.getClass());
        }

        /**
         * 1.调用entrySet方法
         * todo  entrySet方法 返回值是一个set集合
         *      public Set<Map.Entry<K,V>> entrySet() {
         *         Set<Map.Entry<K,V>> es;
         *         return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
         *     }
         *
         * 2.再 (entrySet = new EntrySet()) 创建实例
         * 调用的是HashMap中的一个内部类 EntrySet
         * 这个内部类并没有构造方法，而且继承了AbstractSet的构造方法也是空实现
         * AbstractSet继承的AbstractCollection类的构造方法还是空实现
         *
         * todo
         *      final class EntrySet extends AbstractSet<Map.Entry<K,V>> {...}
         *
         * 3.何时得到的值？？
         * 3.1
         * todo 在AbstractMap中的同String()方法得到了一个entrySet的迭代器
         *      public String toString() {
         *         Iterator<Entry<K,V>> i = entrySet().iterator();
         *         if (! i.hasNext())
         *             return "{}";
         *             }
         *
         *  3.2 回到了HashMap中的一个内部类 EntrySet中有一个静态方法
         *  EntrySet中重写了iterator()方法，实际调用的是EntryIterator对象
         *  todo
         *      public final Iterator<Map.Entry<K,V>> iterator() {
         *             return new EntryIterator();
         *         }
         *
         *  3.3 EntryIterator又是HashMap的一个内部类
         *  todo
         *      final class EntryIterator extends HashIterator
         *         implements Iterator<Map.Entry<K,V>> {
         *         public final Map.Entry<K,V> next() { return nextNode(); }
         *     }
         *
         * 3.4 EntryIterator继承自HashIterator是HashMap中的一个抽象内部类
         * todo
         *      HashIterator() {
         *             expectedModCount = modCount;
         *             Node<K,V>[] t = table;
         *             current = next = null;
         *             index = 0;
         *             if (t != null && size > 0) { // advance to first entry
         *                 do {} while (index < t.length && (next = t[index++]) == null);
         *             }
         *         }
         */
        System.out.println(map);

    }
}
